﻿using System;

namespace ScintillaNET_Editor_Plugin {
    public class ScintillaNetDocument : Notepad_X.Classes.IDocument {
        
        private int _id;
        private Notepad_X.Components.TabPageX _tab_page;
        private string _path;
        private ScintillaNet.Scintilla _text_box;
        private bool _saved = false;
        private bool _available = false;

        private int _find_pos = 0;
        private int _find_index=0;
        private string _find_string = null;
        private bool _watcherChanged=false;
        private System.IO.FileSystemWatcher _watcher;

        public event Notepad_X.Classes.DocumentXEventHandler DocumentChanged;

        public int id { get { return _id; } }
        public Notepad_X.Components.TabPageX tab_page { get { return _tab_page; } }
        public string path { get { return _path; } }

        public bool saved { get { return _saved; } }
        public bool available { get { return _available; } }

        public System.IO.FileSystemWatcher watcher { get { return _watcher; } set { _watcher = value; } }
        public bool watcherChanged { get{return _watcherChanged;} set{_watcherChanged=value;} }
        public System.Drawing.Printing.PrintDocument printDocument { get { return _text_box.Printing.PrintDocument; } }
        public object text_box { get { return _text_box; } }

        public System.Drawing.Font font { get { return _text_box.Font; } set { } }//_text_box.UseFont = true; _text_box.Font = value; } }

        public int find_pos { get { return _find_pos; } set { _find_pos = value; } }
        public int find_index { get { return _find_index; } set { _find_index = value; } }
        public string find_string { get { return _find_string; } set { _find_string = value; } }

        public string text { get { return _text_box.Text; } set { _text_box.Text = value; } }

        private string lastLanguage = null;

        public ScintillaNetDocument(int pId) {
            create(pId);
        }

        public void setColors(System.Drawing.Color Background, System.Drawing.Color Fore) {
            return;
            if (Background != null) {
                _text_box.UseBackColor = true;
                _text_box.BackColor = Background;
            }
           if (Fore != null) {
               _text_box.UseForeColor = true;
               _text_box.ForeColor = Fore;
           }
        }

        public void create(int pId){
            _id = pId;
            _tab_page = new Notepad_X.Components.TabPageX(pId);
            _path = null;
            _text_box = new ScintillaNet.Scintilla();
            _tab_page.AllowDrop = true;
            _tab_page.Controls.Add(_text_box);
            tab_page.id = _id;

            _text_box.Tag = id;
            _text_box.Dock = System.Windows.Forms.DockStyle.Fill;
            _text_box.Location = new System.Drawing.Point(0, 0);
            _text_box.AllowDrop = true;

            _saved = true;
            _available = false;
            _tab_page.ImageKey = "documentok";
            _watcher = null;
            _text_box.SelectionChanged += new EventHandler(_text_box_SelectionChanged);
            _text_box.DocumentChange += new EventHandler<ScintillaNet.NativeScintillaEventArgs>(_text_box_DocumentChange);
            new Notepad_X.Classes.Event.DocumentEvent(id, Notepad_X.Classes.Event.DocumentEvents.New);

            //_text_box.
            //_text_box.Styles[1].BackColor = System.Drawing.Color.Black;
            //_text_box.Styles[2].BackColor = System.Drawing.Color.Black;
            //_text_box.Styles[5].BackColor = System.Drawing.Color.Black;
        }

        void _text_box_SelectionChanged(object sender, EventArgs e) {
            try {
                Notepad_X.Static.MainInstance.StatusBar_Line.Text = "Line : " + (_text_box.Caret.LineNumber + 1) + " Char : " + _text_box.Caret.Position;
            } catch { }
        }

        void _text_box_DocumentChange(object sender, ScintillaNet.NativeScintillaEventArgs e) {
            _saved = false;
            _tab_page.ImageKey = "documentchanged";
            if (DocumentChanged != null) DocumentChanged.Invoke(this, new Notepad_X.Classes.DocumentXEventArgs(_id));
        }

        void _DocumentChanged(object sender, Notepad_X.Classes.DocumentXEventArgs e) {
            _saved = false;
            _tab_page.ImageKey = "documentchanged";
            DocumentChanged -= new Notepad_X.Classes.DocumentXEventHandler(_DocumentChanged); 
        }

        public void clear(){
            _available = true;
            _text_box.Dispose();
            _text_box = null;
            _tab_page.Dispose();
            _tab_page = null;
            _path = null;
            _id = -1;
            _saved = false;
            DocumentChanged = null;
        }

        public void save(string pPath){
            _saved = true;
            _path = pPath;
 
            System.IO.StreamWriter toWrite = new System.IO.StreamWriter(_path,false, _text_box.Encoding);
                    toWrite.Write(_text_box.Text);
                    toWrite.Close();

            _tab_page.ImageKey = "documentok";
    
            //hightlight
            if(plugin.Highlighters)setLanguage();
            DocumentChanged += new Notepad_X.Classes.DocumentXEventHandler(_DocumentChanged);
            new Notepad_X.Classes.Event.DocumentEvent(id, Notepad_X.Classes.Event.DocumentEvents.Save);

        }

        private void setLanguage(string language = null) {
            if (language == null) language = plugin.lngMng.getLanguageForExtension(new System.IO.FileInfo(_path).Extension.ToLower());
            if (language != lastLanguage) {

                if (_text_box.ConfigurationManager.CustomLocation != plugin.directory) _text_box.ConfigurationManager.CustomLocation = plugin.directory;

               lastLanguage=  _text_box.ConfigurationManager.Language = language;
            }

        }

        public void open(string pPath){
            DocumentChanged -= new Notepad_X.Classes.DocumentXEventHandler(_DocumentChanged);
            _path = pPath;
           // _text_box.Encoding = System.Text.Encoding.Default;
            //_text_box.NativeInterface.SetCodePage(System.Text.UTF8Encoding.Default.CodePage);
            System.IO.StreamReader toRead = new System.IO.StreamReader(_path);
            _text_box.Text = toRead.ReadToEnd();
            toRead.Close();

            //highlight
            if (plugin.Highlighters) setLanguage();
           _saved = true;
           _tab_page.ImageKey = "documentok";
           new Notepad_X.Classes.Event.DocumentEvent(id, Notepad_X.Classes.Event.DocumentEvents.Open);
           //DocumentChanged += new Notepad_X.Classes.DocumentXEventHandler(_DocumentChanged);
     
        }

        public void cut(){
            _text_box.Clipboard.Cut();
        }
        public void copy(){
            _text_box.Clipboard.Copy();
        }
        public void paste(){
            _text_box.Clipboard.Paste();
        }
        public void selectAll(){
            _text_box.Selection.SelectAll();
        }

        public string selectedText() {
            return _text_box.Selection.Text;
        }
        public int selectionIndex() {
            return _text_box.Selection.Start;
        }

        public void insert(int index, string text) {
            _text_box.InsertText(index, text);
        }
        public void undo(){
            _text_box.UndoRedo.Undo();
        }
        public void redo(){
            _text_box.UndoRedo.Redo();
        }

        public void print(){
            _text_box.Printing.Print(false);
        }

        public void lineNumbers(bool value){
            if (value) {
                _text_box.Margins[0].Width = 25;
            } else {
                _text_box.Margins[0].Width = 0;
            }
        }

        public void goTo(int line){
            _text_box.GoTo.Line(line);
        }

        public void find(string text){
            _text_box.FindReplace.ShowFind();
        }

        public void replace(string text, string newText) {
            _text_box.FindReplace.ShowReplace();
        }
    
    }
}
